<!-- Copyright 2005 Blandware (http://www.blandware.com) -->
<html>
<head>
</head>
<body>
    <p>
This package contains classes implementing tags that are used in/with Grid (and
Grid itself).
    </p>
    <p>
<em>Grid</em> is an object that serves to displaying some data and navigating it.
Data is represented with <em>rows</em>. Each row corresponds to some object,
that can be stored in persistent storage, for example. Some properties of such
objects are dedicated and called <em>fields</em>. Each field has it's own name
(for example, such names may match names of row columns in database). Fields
may be used to filter rows (so grid will display only a subset of all rows) and
to sort them.
    </p>
    <p>
Each field may have a filter assigned to it. Such assignment is made with
some filter tag. Currently, four types of filters (and four corresponding tags)
are implemented: {@link com.blandware.atleap.webapp.taglib.core.grid.DateFilterTag},
{@link com.blandware.atleap.webapp.taglib.core.grid.NumberFilterTag},
{@link com.blandware.atleap.webapp.taglib.core.grid.SetFilterTag} and
{@link com.blandware.atleap.webapp.taglib.core.grid.StringFilterTag}.
        <ul>
        <li>
<code>DateFilterTag</code> filters its data on data fields
comparing dates.
        </li>
        <li>
<code>NumberFilterTag</code> filters its data on number fields
comparing their values.
        </li>
        <li>
<code>SetFilterTag</code> filters its data checking whether current element
belongs to some set or not.
        </li>
        <li>
<code>StringFilterTag</code> filters its data on string fields checking whether
some string is a substring (or prefix, or something else) and so on.
        </li>
        </ul>
Each filter tag generates a hyperlink, which displays a filter window when
pressed.
    </p>
    <p>
Grid may be sorted by some fields. This sorting may be simultaneous: first
sort is made on one field, then on another and so on (this is similar to
SQL statements: there you can specify several ORDER BY clauses like
SELECT * FROM user ORDER BY last_name, first_name...). Sort is specified with
<em>sort</em> tag, which generates a hyperlink that causes rows to be sorted.
    </p>
    <p>
Grid also gives ability to split rows by pages. This is done with
<em>pager</em>, <em>pagesIterator</em> and other tags.
    </p>
    <p>
Here's an example:
<pre>
&lt;atleap:grid name=&quot;layoutGrid&quot; pageSize=&quot;${pageSize}&quot;&gt;
    &lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;grid&quot;&gt;
        &lt;thead&gt;
            &lt;tr&gt;
                &lt;th nowrap=&quot;nowrap&quot;&gt;
                    &lt;atleap:column fieldName=&quot;l.name&quot; fieldKey=&quot;core.layout.form.name&quot;&gt;
                        &lt;atleap:sort&gt;
                            &lt;atleap:message key=&quot;${fieldKey}&quot; /&gt;
                            &lt;atleap:sortAsc&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/ascSort.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:sortAsc&gt;
                            &lt;atleap:sortDesc&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/descSort.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:sortDesc&gt;
                            &lt;/atleap:sort&gt;
                        &lt;atleap:stringFilter&gt;
                            &lt;atleap:filterEnabled&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/filterEnabled.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:filterEnabled&gt;
                            &lt;atleap:filterDisabled&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/filterDisabled.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:filterDisabled&gt;
                         &lt;/atleap:stringFilter&gt;
                    &lt;/atleap:column&gt;
                &lt;/th&gt;
                &lt;th nowrap=&quot;nowrap&quot;&gt;
                    &lt;atleap:column fieldName=&quot;l.definition&quot; fieldKey=&quot;core.layout.form.definition&quot;&gt;
                        &lt;atleap:sort&gt;
                            &lt;atleap:message key=&quot;${fieldKey}&quot; /&gt;
                            &lt;atleap:sortAsc&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/ascSort.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:sortAsc&gt;
                            &lt;atleap:sortDesc&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/descSort.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:sortDesc&gt;
                        &lt;/atleap:sort&gt;
                        &lt;atleap:stringFilter&gt;
                            &lt;atleap:filterEnabled&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/filterEnabled.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:filterEnabled&gt;
                            &lt;atleap:filterDisabled&gt;
                                &lt;img border=&quot;0&quot; src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/grid/filterDisabled.gif&quot; /&gt;&quot;  /&gt;
                            &lt;/atleap:filterDisabled&gt;
                        &lt;/atleap:stringFilter&gt;
                    &lt;/atleap:column&gt;
                &lt;/th&gt;
                &lt;th colspan=&quot;${1 + additionalCells}&quot;&gt;
                    &lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/spacer.gif&quot; /&gt;&quot; border=&quot;0&quot;  /&gt;
                &lt;/th&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            &lt;atleap:contextMenu var=&quot;menuId&quot;&gt;
                &lt;atleap:rowsIterator beanId=&quot;layoutManager&quot; method=&quot;listLayouts&quot; var=&quot;layout&quot; oddClass=&quot;oddRow&quot; evenClass=&quot;evenRow&quot;&gt;
                    &lt;atleap:itemSet&gt;
                        &lt;atleap:rewriteUrl action=&quot;core/layout/view&quot; var=&quot;defaultUrl&quot;&gt;
                            &lt;atleap:param name=&quot;id&quot; value=&quot;${layout.id}&quot; /&gt;
                        &lt;/atleap:rewriteUrl&gt;
                        &lt;tr class=&quot;${rowClass}&quot; oncontextmenu=&quot;return showContextMenu(${menuId}, event, ${indexId});&quot; onclick=&quot;dispatchGridTrClick(event, this, &amp;#039;${defaultUrl}&amp;#039;);&quot;&gt;
                            &lt;td nowrap=&quot;nowrap&quot;&gt;
                                &lt;c:if test=&quot;${empty layout.cpDefinition}&quot;&gt;
                                    &lt;atleap:message key=&quot;core.layout.form.abstract&quot; /&gt;
                                &lt;/c:if&gt;
                                &lt;c:out value=&quot;${layout.name}&quot; escapeXml=&quot;true&quot; /&gt;
                            &lt;/td&gt;
                            &lt;td&gt;&lt;c:out value=&quot;${layout.definition}&quot; escapeXml=&quot;true&quot; /&gt;&lt;/td&gt;
                            &lt;atleap:item includeInPage=&quot;${isAdmin}&quot; includeInContextMenu=&quot;${isAdmin}&quot;&gt;
                                &lt;td align=&quot;center&quot; width=&quot;20&quot; height=&quot;20&quot; valign=&quot;middle&quot; class=&quot;defaultCursorCell&quot;&gt;
                                    &lt;atleap:itemEnabled&gt;
                                        &lt;atleap:message key=&quot;core.commons.buttons.callUpdate&quot; var=&quot;callUpdateMsg&quot; /&gt;
                                        &lt;atleap:itemLink action=&quot;core/layout/callUpdate&quot;title=&quot;${callUpdateMsg}&quot;&gt;
                                            &lt;atleap:param name=&quot;id&quot; value=&quot;${layout.id}&quot; /&gt;
                                                &lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/edit.gif&quot; /&gt;&quot; border=&quot;0&quot; title=&quot;${callUpdateMsg}&quot; alt=&quot;${callUpdateMsg}&quot; align=&quot;absmiddle&quot; /&gt;
                                                &lt;atleap:itemLabel&gt;
                                                    ${callUpdateMsg}
                                                &lt;/atleap:itemLabel&gt;
                                        &lt;/atleap:itemLink&gt;
                                    &lt;/atleap:itemEnabled&gt;
                                &lt;/td&gt;
                            &lt;/atleap:item&gt;
                            &lt;atleap:item&gt;
                                &lt;td align=&quot;center&quot; width=&quot;20&quot; height=&quot;20&quot; valign=&quot;middle&quot; class=&quot;defaultCursorCell&quot;&gt;
                                    &lt;atleap:itemEnabled&gt;
                                        &lt;atleap:message key=&quot;core.commons.buttons.view&quot; var=&quot;viewMsg&quot;/&gt;
                                        &lt;atleap:itemLink action=&quot;core/layout/view&quot; title=&quot;${viewMsg}&quot;&gt;
                                            &lt;atleap:param name=&quot;id&quot; value=&quot;${layout.id}&quot; /&gt;
                                                &lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/view.gif&quot; /&gt;&quot; border=&quot;0&quot; title=&quot;${viewMsg}&quot; alt=&quot;${viewMsg}&quot; align=&quot;absmiddle&quot; /&gt;
                                                &lt;atleap:itemLabel&gt;
                                                    ${viewMsg}
                                                &lt;/atleap:itemLabel&gt;
                                        &lt;/atleap:itemLink&gt;
                                    &lt;/atleap:itemEnabled&gt;
                                &lt;/td&gt;
                            &lt;/atleap:item&gt;
                            &lt;atleap:item includeInPage=&quot;${isAdmin}&quot; includeInContextMenu=&quot;${isAdmin}&quot;&gt;
                                &lt;td align=&quot;center&quot; width=&quot;20&quot; height=&quot;20&quot; valign=&quot;middle&quot; class=&quot;defaultCursorCell&quot;&gt;
                                    &lt;atleap:itemEnabled&gt;
                                        &lt;atleap:message key=&quot;core.commons.buttons.delete&quot; var=&quot;deleteTitle&quot;/&gt;
                                        &lt;atleap:itemLink action=&quot;core/layout/delete&quot; transaction=&quot;false&quot; confirmExpression=&quot;confirmDelete();&quot; title=&quot;${deleteTitle}&quot;&gt;
                                            &lt;atleap:param name=&quot;id&quot; value=&quot;${layout.id}&quot; /&gt;
                                                &lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/delete.gif&quot; /&gt;&quot; border=&quot;0&quot; title=&quot;${deleteTitle}&quot; alt=&quot;${deleteTitle}&quot; align=&quot;absmiddle&quot; /&gt;
                                                &lt;atleap:itemLabel&gt;
                                                    ${deleteTitle}
                                                &lt;/atleap:itemLabel&gt;
                                        &lt;/atleap:itemLink&gt;
                                    &lt;/atleap:itemEnabled&gt;
                                &lt;/td&gt;
                            &lt;/atleap:item&gt;
                        &lt;/tr&gt;
                    &lt;/atleap:itemSet&gt;
                &lt;/atleap:rowsIterator&gt;
            &lt;/atleap:contextMenu&gt;
             &lt;atleap:noRows&gt;
                &lt;tr&gt;
                    &lt;td class=&quot;tfoot&quot; colspan=&quot;${3 + additionalCells}&quot; align=&quot;center&quot;&gt;
                       &lt;em&gt;&lt;atleap:message key=&quot;core.commons.nothingToShow&quot;/&gt;&lt;/em&gt;
                    &lt;/td&gt;
                &lt;/tr&gt;
             &lt;/atleap:noRows&gt;
        &lt;/tbody&gt;
        &lt;tfoot&gt;
            &lt;tr&gt;
                &lt;atleap:pager pageCount=&quot;10&quot;&gt;
                    &lt;td colspan=&quot;${3 + additionalCells}&quot; align=&quot;center&quot;&gt;
                        &lt;atleap:message key=&quot;core.grid.pager.title&quot; /&gt;&amp;nbsp;
                        &lt;atleap:firstPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/first.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.first&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.first&quot;/&gt;&quot; /&gt;&lt;/atleap:firstPage&gt;
                        &lt;atleap:prevPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/prev.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.prev&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.prev&quot;/&gt;&quot; /&gt;&lt;/atleap:prevPage&gt;
                        &lt;atleap:pagesIterator&gt;
                            &lt;atleap:page&gt;${pageNumber}&amp;nbsp;&lt;/atleap:page&gt;
                            &lt;atleap:currentPage&gt;&lt;b&gt;${pageNumber}&lt;/b&gt;&amp;nbsp;&lt;/atleap:currentPage&gt;
                        &lt;/atleap:pagesIterator&gt;
                        &lt;atleap:nextPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/next.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.next&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.next&quot;/&gt;&quot; /&gt;&lt;/atleap:nextPage&gt;
                        &lt;atleap:lastPage&gt;&lt;img src=&quot;&lt;atleap:rewriteUrl href=&quot;/images/theme/atleap_admin/last.gif&quot; /&gt;&quot; border=&quot;0&quot; alt=&quot;&lt;atleap:message key=&quot;core.grid.pager.last&quot;/&gt;&quot; title=&quot;&lt;atleap:message key=&quot;core.grid.pager.last&quot;/&gt;&quot; /&gt;&lt;/atleap:lastPage&gt;
                    &lt;/td&gt;
                &lt;/atleap:pager&gt;
            &lt;/tr&gt;
        &lt;/tfoot&gt;
    &lt;/table&gt;
&lt;/atleap:grid&gt;
</pre>
This will render a table. Its rows will represent data rows, cells will
contain data for fields. First two fields are sortable and filterable (filtering
may be made with string filter).
    </p>
    <p>
Each row will contain icons representing operations over rows. Also, every row
will have a corresponding context menu.
    </p>
    <p>
A pager will be rendered after data table (if there's a need -- more then 10
elements).
    </p>
    <p>
Rows will alternate: row with class 'oddRow' - row with class 'evenRow' -
row with class 'oddRow' and so on. Each row is pressable: when a user presses
on a row (not on link), it will have the same effect as if he/she pressed on
'view' icon.
    </p>
</body>
</html>